home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / amiexpress / mods / newchat233 / newchat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-22  |  31.8 KB  |  839 lines

  1. #include <exec/exec.h>
  2. #include <exec/semaphores.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <time.h>
  6. #include "sc:ae/CmodGlue/doorheader.h"
  7. #include <clib/exec_protos.h>
  8. #include <clib/alib_protos.h>
  9. #include <clib/dos_protos.h>
  10. #include <string.h>
  11. #include "sc:ae/CmodGlue/glue.h"
  12. extern struct JHMessage *Jhmsg;
  13. #define CHAT_ENTER 5
  14. #define CHAT_EXIT  4
  15. #define CHAT_IDLE  3
  16. #define CHAT_TEXT  2
  17. #define CHAT_NONE  1
  18. #define CHAT_NTXT  6
  19. #define CHAT_CHANNEL 7
  20. #define CHAT_INVITE 8
  21. #define CHATROOM_EXIT 9
  22. #define CHAT_TIMEOUT 10
  23. #define ALL -1
  24. #define pu putuserstring
  25. #define gu getuserstring
  26. #define sm sendmessage
  27. #define pm prompt
  28. #define CTRL(c) (c-'A'+1)
  29.  char myname[40];
  30.  
  31. struct NodeStat
  32. {
  33.   char Status;
  34.   char info;
  35. };
  36. struct NodeInfo
  37. {
  38.   char Handle[31];
  39.   ULONG StartTime;
  40.   int ChatColor;
  41.   int Channel;
  42.   int Private;
  43.   struct NodeStat Stats[10];
  44.   APTR t;
  45.   APTR s;
  46.   unsigned long tasksignal;
  47. };
  48.  
  49. struct MultiPort
  50. {
  51.   struct SignalSemaphore semi;
  52.   struct MinList sl_List;
  53.   struct NodeInfo MyNode[10];
  54.   UBYTE SemiName[20];
  55. } *Nodes;
  56.  
  57. struct SinglePort
  58. {
  59.   struct SignalSemaphore semi;
  60.   struct MinList sl_List;
  61.   APTR s;
  62.   UBYTE SemiName[20];
  63.   int Status;
  64.   char Handle[31];
  65.   char Location[31];
  66.   char Misc1[100];
  67.   char Misc2[100];
  68. } *SingleNode;
  69.  
  70. APTR Singles[10];
  71. char MultiName[] = "AEMulti";
  72. LONG Time_limit;
  73. LONG Time_Used;
  74. ULONG Time_holder=0L;
  75. ULONG Time_system;
  76.  
  77. void my_Interact(void);
  78. void SendSig(int node);
  79. void InitNodes(struct MultiPort *s);
  80. void InitMultiNode(void);
  81. void LastCommand(void);
  82. void end(void);
  83. void creds(void);
  84. void ShowActive(void);
  85. void page(void);
  86. void ShowMenu(void);
  87. void Process(int opt, int info);
  88. void who(int opt);
  89. void check_online_status(int rel);
  90. int mynode;
  91. #define hk hotkey
  92. struct MsgPort *mychatp;
  93. char SingleName[] = "AEStat ";
  94. int defaultroom=0;
  95. main(int argc,char *argv[])
  96. {
  97.    char t[200];
  98.    int chatargc;
  99.    register int i;
  100.    if(argc!=2)
  101.    {
  102.      printf("MultiNode Chat by ByteMaster, version 3.1\n");
  103.      printf("\n");
  104.      exit(0);
  105.    }
  106.    Register(argv[1][0]-'0');
  107.    mynode=argv[1][0]-'0';
  108.    mychatp=CreatePort(0,0L);
  109.  getuserstring(t,BB_TASKPRI);
  110.   SetTaskPri(FindTask(0),atol(t));
  111.    strcpy(t,"25"); pu(t,ENVSTAT);
  112.    PutInfo(1,BB_NONSTOPTEXT);
  113.    gu(t,BB_MAINLINE);
  114.    i=0; while(t[i]!='\0')
  115.    {
  116.       if(t[i]==' ' && t[i+1]!='\0')
  117.         { defaultroom=atoi(&t[i+1]);
  118.           if(defaultroom>1000) defaultroom=0;
  119.           if(defaultroom<0) defaultroom=0;
  120.           break;
  121.         }
  122.       i++;
  123.    }
  124.    InitMultiNode();
  125.    my_Interact();
  126. }
  127. void InitNodes(struct MultiPort *s)
  128. {
  129.   register int i=0;
  130.   register int j=0;
  131.   while(i<9)
  132.   {
  133.      strcpy(s->MyNode[i].Handle,"");
  134.      for(j=0;j<9;j++)
  135.      {
  136.        s->MyNode[i].Stats[j].info='\0';
  137.        s->MyNode[i].Stats[j].Status=CHAT_NONE;
  138.        if(j==mynode && j!=i) s->MyNode[i].Stats[j].Status=CHAT_IDLE;
  139.      }
  140.      
  141.      s->MyNode[i].t=NULL;
  142.      s->MyNode[i].tasksignal=NULL;
  143.      s->MyNode[i].StartTime=NULL;
  144.      i++;
  145.   }
  146. }
  147. void InitMultiNode(void)
  148. {
  149.   unsigned long signal;
  150.   
  151.   register int i,j;
  152.   int status;
  153.   Jhmsg->signal= getsignal();
  154.   signal = 1L << (Jhmsg->signal);
  155.   pu("",BB_GETTASK);
  156.   gu(myname,DT_NAME);
  157.   
  158.   Nodes=(struct MultiPort *)GetSemaphore();
  159.     ObtainSemaphore((struct SignalSemaphore *)Nodes);
  160.       SingleNode=(struct SinglePort *)Nodes->MyNode[mynode].s;
  161.       ObtainSemaphore((struct SignalSemaphore *)SingleNode);
  162.        status = SingleNode->Status;
  163.       ReleaseSemaphore((struct SignalSemaphore *)SingleNode);
  164.  
  165.     for(i=0;i<9;i++)
  166.     {
  167.       for(j=0;j<9;j++)
  168.       {
  169.         if(i!=mynode && j==mynode)
  170.         {
  171.             Nodes->MyNode[i].Stats[j].Status=CHAT_ENTER;
  172.             if(Nodes->MyNode[i].Channel==defaultroom) Nodes->MyNode[i].Stats[j].info=(status>=-1)? 1:0;
  173.             else Nodes->MyNode[i].Stats[j].info=0;
  174.         }
  175.       }
  176.       Singles[i]=Nodes->MyNode[i].s;
  177.       if(Nodes->MyNode[mynode].Stats[i].Status==CHAT_EXIT || Nodes->MyNode[mynode].Stats[i].Status==CHAT_NONE)Nodes->MyNode[mynode].Stats[i].Status=CHAT_NONE;
  178.       else Nodes->MyNode[mynode].Stats[i].Status=CHAT_IDLE ;
  179.     }
  180.       strcpy(Nodes->MyNode[mynode].Handle,myname);
  181.          Nodes->MyNode[mynode].tasksignal=signal;
  182.        Nodes->MyNode[mynode].t=(struct Task *)Jhmsg->aeproc;
  183.        Nodes->MyNode[mynode].Channel=defaultroom;
  184.        Nodes->MyNode[mynode].Private=0;
  185.        Nodes->MyNode[mynode].StartTime=time(NULL);
  186.     check_online_status(0);
  187.     ShowActive();
  188.     sm("",1);
  189.     sm("Press <CTRL-F> to see Functions",1); sm("",1);
  190.     SendSig(ALL);
  191.     ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  192.     
  193. }
  194.  
  195. void SendSig(int node)
  196. {
  197.    register int i=0;
  198.    while(i<9)
  199.    {
  200.      if(i!=mynode && (node==-1 || node==i))
  201.      {
  202.        if(Nodes->MyNode[i].t !=NULL && Nodes->MyNode[mynode].Stats[i].Status!=CHAT_NONE)
  203.          Signal(Nodes->MyNode[i].t,Nodes->MyNode[i].tasksignal);
  204.      }
  205.      i++;
  206.    }
  207. }
  208. void my_Interact(void)
  209. {
  210.    char mes[10];
  211.    char temp[100];
  212.    char temp1[100];
  213.    char temp2[10];
  214.    int lastchannel;
  215.    int status=0;
  216.    register int i;
  217.    char t[10];
  218.    int Last=0;
  219.    strcpy(mes,"");
  220.    strcpy(temp,"");
  221.    mes[1]='\0';
  222.    strcpy(temp," m");
  223.    Process(1,0);
  224.    Last=2;
  225.    check_online_status(0);
  226.    while(1)
  227.    {
  228.       mes[0]=sigkey();
  229.       switch(mes[0])
  230.       {
  231.          case 0:
  232.               ObtainSemaphore((struct SignalSemaphore *)Nodes);
  233.               for(i=0;i<9;i++)
  234.               {
  235.                 if(i!=mynode)
  236.                 {
  237.                 switch(Nodes->MyNode[mynode].Stats[i].Status)
  238.                 {
  239.                   case CHAT_NTXT:
  240.                      if(Nodes->MyNode[mynode].Channel==Nodes->MyNode[i].Channel)
  241.                      {
  242.                       temp[3]=Nodes->MyNode[i].ChatColor+'0';
  243.                       sm("",1);Process(1,0);
  244.                        sm(temp,0); sm(Nodes->MyNode[i].Handle,0); sm("> ",0);
  245.                        Process(2,strlen(Nodes->MyNode[i].Handle)+2);
  246.                        Last = 2;
  247.                      if(Nodes->MyNode[mynode].Stats[i].info==10 ||
  248.                         Nodes->MyNode[mynode].Stats[i].info==13)
  249.                      { sm("",1); Process(1,0);  check_online_status(1);} else  
  250.                      { sm(temp,0); Process(0,Nodes->MyNode[mynode].Stats[i].info); }
  251.                       }
  252.                      Nodes->MyNode[mynode].Stats[i].Status=CHAT_IDLE;
  253.                       break;
  254.                      case CHAT_TEXT:
  255.                      if(Nodes->MyNode[mynode].Channel==Nodes->MyNode[i].Channel)
  256.                      {
  257.                      temp[3]=Nodes->MyNode[i].ChatColor+'0';
  258.                       if(Nodes->MyNode[mynode].Stats[i].info==10 ||
  259.                         Nodes->MyNode[mynode].Stats[i].info==13)
  260.                      { sm("",1); Process(1,0); check_online_status(1);} else  
  261.                      { sm(temp,0); Process(0,Nodes->MyNode[mynode].Stats[i].info); }
  262.                      }  
  263.                       Nodes->MyNode[mynode].Stats[i].Status=CHAT_IDLE;
  264.                      
  265.                               break;
  266.                   case CHAT_ENTER:
  267.                      if(Nodes->MyNode[mynode].Stats[i].info==1)
  268.                      {
  269.                      sm("",1);
  270.                      temp[3]=Nodes->MyNode[i].ChatColor+'0'; Process(1,0);
  271.                      sm(temp,0); sm(Nodes->MyNode[i].Handle,0);
  272.                      sm(" enters chat room.",1); Last=2;
  273.                      }
  274.                      Nodes->MyNode[mynode].Stats[i].Status=CHAT_IDLE;
  275.                      break;
  276.                   case CHATROOM_EXIT:
  277.                      if(Nodes->MyNode[mynode].Stats[i].info==1)
  278.                      {
  279.                      sm("",1);
  280.                      temp[3]=Nodes->MyNode[i].ChatColor+'0'; Process(1,0);
  281.                      sm(temp,0);
  282.                      sm(Nodes->MyNode[i].Handle,0);
  283.                      sm(" exits chat room.",1); Last=2;
  284.                      }
  285.                      Nodes->MyNode[mynode].Stats[i].Status=CHAT_IDLE;
  286.                      break;
  287.                 case CHAT_EXIT:
  288.                      if(Nodes->MyNode[mynode].Stats[i].info==1)
  289.                      {
  290.                      sm("",1);
  291.                      temp[3]=Nodes->MyNode[i].ChatColor+'0'; Process(1,0);
  292.                      sm(temp,0);
  293.                      sm(Nodes->MyNode[i].Handle,0);
  294.                      sm(" exits chat room.",1); Last=2;
  295.                      }
  296.                      Nodes->MyNode[mynode].Stats[i].Status=CHAT_NONE;
  297.                      break;
  298.                 case CHAT_TIMEOUT:
  299.                      if(Nodes->MyNode[mynode].Stats[i].info==1)
  300.                      {
  301.                       sm("",1);
  302.                       temp[3]=Nodes->MyNode[i].ChatColor+'0'; Process(1,0);
  303.                       sm(temp,0);
  304.                       sm(Nodes->MyNode[i].Handle,0);
  305.                       sm("'s time has expired.",1); Last=2;
  306.                      }
  307.                      Nodes->MyNode[mynode].Stats[i].Status=CHAT_NONE;
  308.                      break;
  309.                   case CHAT_INVITE:
  310.                      sm("",1);
  311.                      sprintf(temp1,"Chat Invitation from Room (%d)",Nodes->MyNode[i].Channel);
  312.                      sm(temp1,1); sm("",1);
  313.                      Process(1,0); Last=2;
  314.                      break;
  315.                  }
  316.                 }
  317.               }
  318.               ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  319.               break;
  320.          case CTRL('X'): ShutDown(); end();
  321.               break;
  322.          case CTRL('V'): creds(); break;
  323.          case CTRL('F'):
  324.               ShowMenu(); Process(1,0); Last=2;break;
  325.          case CTRL('N'): who(0); Process(1,0); Last=2; break;
  326.          case CTRL('D'): who(1); Process(1,0); Last=2; break;
  327.          case CTRL('P'): page(); Process(1,0); Last=2; sm("",1); break;
  328.          case CTRL('A'): ObtainSemaphore((struct SignalSemaphore *)Nodes);
  329.               ShowActive(); ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  330.               Process(1,0); Last=2; sm("",1);
  331.               break;
  332.          case CTRL('I'): ObtainSemaphore((struct SignalSemaphore *)Nodes);
  333.               ShowActive();  ReleaseSemaphore((struct SignalSemaphore *)Nodes); Process(1,0); Last=2; sm("",1);
  334.               hk("Which Node you wish to Invite or (enter) to abort >:",temp1);
  335.               i=atoi(temp1);
  336.               if(temp1[0]=='\0' || temp1[0]==13 || temp1[0]==10 || i<0 || i>8)
  337.               {
  338.                 sm("Aborting.",1); sm("",1); 
  339.               }
  340.               else
  341.               {
  342.                 sm(temp1,1); sm("",1);
  343.                 ObtainSemaphore((struct SignalSemaphore *)Nodes);
  344.                 if(Nodes->MyNode[mynode].Stats[i].Status!=CHAT_NONE && Nodes->MyNode[mynode].Stats[i].Status!=CHAT_EXIT && i!=mynode &&
  345.                    Nodes->MyNode[i].Channel!=Nodes->MyNode[mynode].Channel)
  346.                 {
  347.                    Nodes->MyNode[i].Stats[mynode].Status=CHAT_INVITE;
  348.                    Signal(Nodes->MyNode[i].t,Nodes->MyNode[i].tasksignal);
  349.                    sm("Node (",0); sm(temp1,0); sm("Invited!",1);
  350.                    sm("",1); 
  351.                 }
  352.                 else
  353.                 {
  354.                   sm("Invalid Request",1); sm("",1);
  355.                 }
  356.                 ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  357.               }
  358.               break;
  359.          case CTRL('R'): ObtainSemaphore((struct SignalSemaphore *)Nodes);
  360.               lastchannel=Nodes->MyNode[mynode].Channel;
  361.               Nodes->MyNode[mynode].Channel=-1;
  362.               ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  363.               sm("",1);
  364.               sm("Enter New Room# or (enter) to remain >:",0);
  365.               pm("",temp1,4);
  366.               if(temp1[0]=='\0' || temp1[0]==13 || temp1[0]==10 || atoi(temp1)<0 || atoi(temp1)>1000)
  367.               {
  368.                 ObtainSemaphore((struct SignalSemaphore *)Nodes);
  369.                 Nodes->MyNode[mynode].Channel=lastchannel;
  370.                 ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  371.                 sm("",1);
  372.                 sm("Remaining in current Room.",1);
  373.                 sm("",1);
  374.                 Process(1,0);
  375.                 Last=2;
  376.               }
  377.               else
  378.               {
  379.                 sm("Private (Y/n>:",0);
  380.                 hk("",temp2); if(temp2[0]=='N' || temp2[0]=='n')
  381.                 {
  382.                    sm("No.",1);
  383.                 }else sm("Yes.",1);
  384.                 ObtainSemaphore((struct SignalSemaphore *)Nodes);
  385.                   SingleNode=(struct SinglePort *)Nodes->MyNode[mynode].s;
  386.                   ObtainSemaphore((struct SignalSemaphore *)SingleNode);
  387.                     status=SingleNode->Status;
  388.                   ReleaseSemaphore((struct SignalSemaphore *)SingleNode);
  389.                 Nodes->MyNode[mynode].Channel=atoi(temp1);
  390.                 if(temp2[0]!='N' && temp2[0]!='n')Nodes->MyNode[mynode].Private=TRUE;
  391.                 else Nodes->MyNode[mynode].Private = FALSE;
  392.                 for(i=0;i<9;i++)
  393.                 {
  394.                   if(i!=mynode)
  395.                   {
  396.                   if(Nodes->MyNode[i].Channel==Nodes->MyNode[mynode].Channel)
  397.                   {
  398.                      Nodes->MyNode[i].Stats[mynode].Status=CHAT_ENTER;
  399.                      Nodes->MyNode[i].Stats[mynode].info=(status>=-1) ?1:0;
  400.                   }
  401.                   else 
  402.                   {
  403.                      if(Nodes->MyNode[i].Channel==lastchannel)
  404.                      {
  405.                         Nodes->MyNode[i].Stats[mynode].info=(status>=-1) ?1:0;
  406.                         Nodes->MyNode[i].Stats[mynode].Status=CHATROOM_EXIT;
  407.                      }
  408.                      else {
  409.                             Nodes->MyNode[i].Stats[mynode].info=0;
  410.                             Nodes->MyNode[i].Stats[mynode].Status=CHATROOM_EXIT;
  411.                           }
  412.                   }
  413.                  if(Nodes->MyNode[i].t!=NULL && Nodes->MyNode[mynode].Stats[i].Status!=CHAT_EXIT &&
  414.                       Nodes->MyNode[mynode].Stats[i].Status!=CHAT_NONE)
  415.                    Signal(Nodes->MyNode[i].t,Nodes->MyNode[i].tasksignal);
  416.            
  417.                  }
  418.                 }  
  419.                 ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  420.                 sm("Moving to Room (",0);
  421.                 sm(temp1,0); sm(")",1);
  422.                 
  423.                 sm("",1);
  424.                 Process(1,0);
  425.                 Last=2;
  426.               }
  427.                 break; 
  428.          default:
  429.               if(Last==1 && mes[0]!=13 && mes[0]!=10) { Last=2; }
  430.               ObtainSemaphore((struct SignalSemaphore *)Nodes);
  431.               temp[3]=Nodes->MyNode[mynode].ChatColor+'0';
  432.             
  433.               for(i=0;i<9;i++)
  434.               {
  435.                  if(i!=mynode && Nodes->MyNode[i].Channel==Nodes->MyNode[mynode].Channel)
  436.                  {
  437.                    Nodes->MyNode[i].Stats[mynode].info=mes[0];
  438.                    if(Last==2)
  439.                    Nodes->MyNode[i].Stats[mynode].Status=CHAT_NTXT;
  440.                       else Nodes->MyNode[i].Stats[mynode].Status=CHAT_TEXT;
  441.                    if(Nodes->MyNode[i].t!=NULL && Nodes->MyNode[mynode].Stats[i].Status!=CHAT_EXIT &&
  442.                       Nodes->MyNode[mynode].Stats[i].Status!=CHAT_NONE)
  443.                    Signal(Nodes->MyNode[i].t,Nodes->MyNode[i].tasksignal);
  444.                  }
  445.                 
  446.               }
  447.               
  448.               ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  449.          if(mes[0]==13 || mes[0]==12 ) { sm("",1); Last=1; Process(1,0);} else {
  450.               if(Last==2) { check_online_status(0);
  451.                 sm(temp,1); Process(1,0);  sm(myname,0); sm("> ",0);
  452.                 Process(2,strlen(myname)+2); }Last=0; sm(temp,0);Process(0,mes[0]); }
  453.               break;
  454.       }
  455.    }
  456. }
  457. char Buf[100];
  458. void Process(int opt, int info)
  459. {
  460.   static int Buffer=0;
  461.   static int LastSpace=0;
  462.   int FoundSpace;
  463.   register int i;
  464.   char singlebuf[2];
  465.   if(opt==2)
  466.   {
  467.     i=0; while(i<info) { Buf[i]=' '; i++; }
  468.     Buffer=info-1;
  469.     LastSpace=Buffer+1;
  470.     return;
  471.   }
  472.   if(opt==1)
  473.   {
  474.     i=0; while(i<3) { Buf[i]=' '; i++; }
  475.     LastSpace=0;
  476.     Buffer=0;
  477.     return;
  478.   }
  479.   
  480.   if((info==8 || info=='\b' )&& Buffer>=LastSpace)
  481.   {
  482.      sm("\b \b",0); 
  483.     Buffer -=1;// if(Buffer<0) Buffer=0;
  484.    
  485.     return;
  486.   }else if(info==8 || info=='\b') return;
  487.   Buffer++;
  488.   if(Buffer<0) { sm("",1); sm("Buffer Error",1); return;}
  489.   if(Buffer==79)
  490.   {
  491.       Buf[80]='\0';
  492.       i=strlen(Buf)-1;
  493.       FoundSpace=0;
  494.       while(i>=0)
  495.       {
  496.          if(Buf[i]==' ') { FoundSpace=1; i++; break;}
  497.          i--;
  498.       }
  499.       
  500.       if(FoundSpace)
  501.       {
  502.         FoundSpace=strlen(&Buf[i]); 
  503.         while(FoundSpace) { sm("\b \b",0); FoundSpace--; }
  504.         sm("",1);
  505.         if(Buf[i]!=' ')
  506.         sm(&Buf[i],0);
  507.         Buffer=0;
  508.         while(Buf[i]!='\0') { Buf[Buffer]=Buf[i]; Buffer++; i++; }
  509.         
  510.       }
  511.       else { Buffer=0; }
  512.       LastSpace=0;
  513.   }
  514.    singlebuf[0]=info; singlebuf[1]='\0'; sm(singlebuf,0); Buf[Buffer]=info;
  515. }  
  516.  
  517. int timedout=0;
  518. void LastCommand(void)
  519. {
  520.    register int i;
  521.    int status; 
  522.    DeletePort((struct MsgPort *)mychatp);
  523.    ObtainSemaphore((struct SignalSemaphore *)Nodes);
  524.      SingleNode=(struct SinglePort *)Nodes->MyNode[mynode].s;
  525.      ObtainSemaphore((struct SignalSemaphore *)SingleNode);
  526.       status=SingleNode->Status;
  527.      ReleaseSemaphore((struct SignalSemaphore *)SingleNode);
  528. Nodes->MyNode[mynode].t=NULL;
  529.    for(i=0;i<9;i++)
  530.    {
  531.      
  532.      Nodes->MyNode[i].Stats[mynode].Status= timedout ?CHAT_TIMEOUT:CHAT_EXIT;
  533.  if(Nodes->MyNode[i].t!=NULL && i!=mynode && Nodes->MyNode[mynode].Stats[i].Status!=CHAT_NONE &&
  534.     Nodes->MyNode[mynode].Stats[i].Status!=CHAT_EXIT && Nodes->MyNode[mynode].Stats[i].Status!=CHAT_TIMEOUT)
  535.     {
  536.        if(Nodes->MyNode[i].Channel==Nodes->MyNode[mynode].Channel)
  537.         Nodes->MyNode[i].Stats[mynode].info=(status>=-1)?1:0; else Nodes->MyNode[i].Stats[mynode].info=0;
  538.  
  539.      Signal(Nodes->MyNode[i].t,Nodes->MyNode[i].tasksignal);
  540.     }
  541.    }
  542.    ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  543.    PutInfo(0,BB_NONSTOPTEXT);
  544.    sm("",1);
  545. }
  546. void end(void)
  547. {
  548.   exit(0);
  549. }
  550. void creds(void)
  551. {
  552.   sm("",1);
  553.   sm( "           .-----------------------------------------------------.",1);
  554.   sm( "           | Ami-Express Multi-Node Interactive Chat Version 3.1 |",1);
  555.   sm( "           |               Written by Joseph Hodge.              |",1);
  556.  // sm( "           |             v2.9 Beta for UnLawful Entry.           |",1);
  557.   sm( "           |      /X Development Team - The Silent Achievers     |",1);
  558.   sm( "           `-----------------------------------------------------'",1);
  559.   sm("",1);
  560. }
  561.  
  562. void ShowActive(void)
  563. {
  564.   register int i;
  565.   register int status;
  566.   char temp1[200]; sm("",1);
  567.   check_online_status(0);
  568.  sm("Users in chat",1);
  569.             sm("-------------",1);
  570.   for(i=0;i<9;i++)
  571.       {
  572.   SingleNode=(struct SinglePort *)Nodes->MyNode[i].s;
  573.           
  574.   ObtainSemaphore((struct SignalSemaphore *)SingleNode);
  575.               status=SingleNode->Status;
  576.            ReleaseSemaphore((struct SignalSemaphore *)SingleNode);
  577.  
  578.         if((Nodes->MyNode[mynode].Stats[i].Status!=CHAT_EXIT &&
  579.            Nodes->MyNode[mynode].Stats[i].Status!=CHAT_NONE) || i==mynode)
  580.           {
  581.            if(status>=-1 || mynode==i)
  582.            {
  583.            if(!Nodes->MyNode[i].Private || i==mynode || Nodes->MyNode[i].Channel==Nodes->MyNode[mynode].Channel)
  584.            sprintf(temp1,"Rm(%4d) Node %dm %d (%4ld mins)> %dm%s",Nodes->MyNode[i].Channel,i+1,i,(time(NULL)-Nodes->MyNode[i].StartTime)/60L,i+1,Nodes->MyNode[i].Handle);
  585.            else           
  586.            sprintf(temp1,"Rm(   ?) Node %dm %d (%4ld mins)> %dm%s",i+1,i,(time(NULL)-Nodes->MyNode[i].StartTime)/60L,i+1,Nodes->MyNode[i].Handle);
  587.            sm(temp1,1);
  588.            }
  589.           }
  590.         }
  591.    sm("",1);
  592.    sprintf(temp1,"Time Remaining (%ld)",Time_limit/60L);
  593.    sm(temp1,1);
  594.    sm("",1);
  595. }
  596.  
  597. void page(void)
  598. {
  599. char inp[100], portnm[100], mes[100];
  600. int status;
  601. long portsig;
  602. struct MsgPort *otport;
  603. struct JHMessage pagemsg;
  604.     portsig=1<<mychatp->mp_SigBit;
  605.   
  606.   sm("",1);
  607.  
  608.   while(1)
  609.   {
  610.   hk( "- Page Which Node? [Node #] Or [Q] To Quit: " ,inp); 
  611.    if(inp[0]=='Q' || inp[0]=='q') { sm(inp,1); return;}
  612.    if(atoi(inp)>=0 && atoi(inp)<9 && atoi(inp)!=mynode){ sm(inp,1);break;}
  613.    sm("",1);
  614.   } 
  615.   SingleName[6]=inp[0];
  616.   sm("",1);
  617.   sprintf( portnm, "AEServer.%d", atoi(inp));
  618.   ObtainSemaphore((struct SignalSemaphore *)Nodes);
  619.      SingleNode=(struct SinglePort *)Nodes->MyNode[atoi(inp)].s;
  620.   ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  621.   if(SingleNode)
  622.   {
  623.     
  624.    ObtainSemaphore((struct SignalSemaphore *)SingleNode);
  625.    status=SingleNode->Status;
  626.    ReleaseSemaphore((struct SignalSemaphore *)SingleNode);
  627.   if(status==0)
  628.   {
  629.   otport = FindPort( (UBYTE *)portnm );
  630.   if( otport == 0 ) { sm( "- Node Unavailable!",1); ReleaseSemaphore((struct SignalSemaphore *)SingleNode);return; }
  631.   pagemsg.Msg.mn_Node.ln_Type=NT_MESSAGE;
  632.   pagemsg.Msg.mn_Length=sizeof(struct JHMessage);
  633.   pagemsg.Msg.mn_ReplyPort=mychatp;
  634.   pagemsg.Data = 0;
  635.   pagemsg.Command = 3;
  636.   sprintf(pagemsg.String,
  637.    "\a\n\r\n\rChat Request! From Node:%d ) User[%s]\n\r\n\r", mynode, Nodes->MyNode[mynode].Handle );
  638.   PutMsg(otport, (struct Message *)&pagemsg);
  639.   WaitPort(mychatp);GetMsg(mychatp);
  640.   pagemsg.Command = 3;
  641.   sprintf(pagemsg.String, "Press [Return] To Resume BBS Operations. Use [CHAT] To Chat With %s\n\r\n\r", Nodes->MyNode[mynode].Handle );
  642.   PutMsg(otport, (struct Message *)&pagemsg);
  643.   WaitPort(mychatp);
  644.   GetMsg(mychatp);
  645.   }
  646.    switch(status)
  647.   {
  648.      case 0:sprintf( mes, "- Chat Request Sent To Node:%d )", atoi(inp)); break;
  649.      case 1:  strcpy( mes, "- User is Downloading."); break;
  650.      case 2:  strcpy( mes, "- User is Uploading."); break;
  651.      case 3:  strcpy( mes, "- User is In a door."); break;
  652.      case 4:  strcpy( mes, "- User is Reading Mail."); break;
  653.      case 5:  strcpy( mes, "- User is Reviewing Stats."); break;
  654.      case 6:  strcpy( mes, "- User is Account Editing."); break;
  655.      case 7:  strcpy( mes, "- User is Zooming."); break;
  656.      case 8:  strcpy( mes, "- User is Viewing File Listings."); break;
  657.      case 9:  strcpy( mes, "- User is Reading Bulletins."); break;
  658.      case 10: strcpy( mes, "- User is Viewing Files."); break;
  659.     case 11:  strcpy( mes, "- Account Sequence."); break;
  660.      case 12:  strcpy( mes, "- User is Logging Off."); break;
  661.      case 13:  strcpy( mes, "- User is Sysoping."); break;
  662.      case 14:  strcpy( mes, "- User is using Shell."); break;
  663.      case 15:  strcpy( mes, "- User is using the EDITOR.");break;
  664.      case 16:  strcpy( mes, "- User is Joining a Conference.");break;
  665.      case 17:  strcpy( mes, "- User is Chatting.");break;
  666.      case 18:  strcpy( mes, "- NODE INACTIVE.");break;
  667.      case 19:  strcpy( mes, "- User is Requesting Sysop Chat.");break;
  668.      case 20:  strcpy( mes, "- User is Connecting.");break;
  669.      case 21:  strcpy( mes, "- User is logging on.");break;
  670.      case 22:  strcpy( mes, "- Node is Awaiting Connect.");break;
  671.      case 23:  strcpy( mes, "- User is Scanning Mail.");break;
  672.      case 24:  strcpy( mes, "- Node is ShutDown.");break;
  673.      case 25:  strcpy( mes, "- User is in MultiChat.");break;
  674.      case 26:  strcpy( mes, "- Node is Suspended.");break;
  675.      case 27:  strcpy( mes, "- Node is Reserved.");break;
  676.      case -1:  strcpy( mes, "- Node is unavailable.");break;
  677.      default: strcpy(mes,"- NODE INACTIVE.");
  678.   }
  679.    sm( mes,1 );
  680.    if(status!=0)
  681.    {
  682.      sm("Chat Denied",1);
  683.    }
  684.   }
  685.   else
  686.   sm("Cannot Locate Node",1);
  687.   return;
  688.  
  689. }
  690.  
  691. void ShowMenu(void)
  692. {
  693.   sm("",1);
  694.   sm("<CTRL-A> Active Chatters",1);
  695.   sm("<CTRL-I> Invite Node",1);
  696.   sm("<CTRL-N> WHO's Online",1);
  697.   sm("<CTRL-P> Page Node",1);
  698.   sm("<CTRL-R> Change Rooms",1);
  699.   sm("<CTRL-X> Exit Chat",1);
  700.   sm("<CTRL-V> View Credits",1);
  701.   sm("",1);
  702. }
  703.  
  704. void who(int opt) 
  705. {
  706. char FileName[100], mes[100],mes2[100],mes1[100];
  707. char Name[100],Location[100];
  708. struct SinglePort *s;
  709. int status;
  710. int i=0;
  711. Delay(10L);
  712.  sm("",1);
  713.  sm("",1);
  714.  sm(".---+----------------------+---------------------------+----------------------.",1);
  715.  
  716.   sm("|Nd#| Name/Handle          Location         ",0);
  717.   sm("         | Action               |",1);
  718.   sm(")---+----------------------+---------------------------+----------------------(",1);
  719.   i=0;
  720.   
  721.   while(i<9)
  722.   {
  723.    ObtainSemaphore((struct SignalSemaphore *)Singles[i]);
  724.    s=(struct SinglePort *)Singles[i];
  725.   status=s->Status;
  726.   strcpy(Name,s->Handle);
  727.   strcpy(Location,s->Location);
  728.   strcpy(FileName,s->Misc1);
  729.    if(opt)
  730.   {
  731.       sprintf(mes, "%-20ld | %-25ld |",(ULONG)s,(ULONG)Nodes);sprintf(mes1," %-20d |",s->semi.ss_NestCount); 
  732.       sprintf(mes2,"%d ",i);
  733.          sm(mes2,0); sm(mes,0); sm(mes1,1);
  734.      sm("|---+----------------------+---------------------------+----------------------|",1);
  735.    ReleaseSemaphore((struct SignalSemaphore *)Singles[i]);
  736.  i++; continue;
  737.   }
  738.   ReleaseSemaphore((struct SignalSemaphore *)Singles[i]);
  739.  
  740.   switch(status)
  741.   {
  742.      case 0:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","IDLE"); break;
  743.      case 1:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);
  744.               if(FileName[0]!='\0')
  745.                sprintf(mes1," DL: %-16.16s |",FileName);
  746.               else
  747.               sprintf(mes1," %-20.20s |","BEGINNING DL"); break;
  748.      case 2:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);
  749.               if(FileName[0]!='\0')
  750.                sprintf(mes1," UL: %-16.16s |",FileName);
  751.               else sprintf(mes1," %-20.20s |","BEGINNING UL"); break;
  752.      case 3:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);
  753.      if(i==mynode)
  754.      sprintf(mes1," %-20.20s |","InfoNode v2.3a"); else
  755.     sprintf(mes1," %-20.20s |","MODULE"); break;
  756.      case 4:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","READING MAIL"); break;
  757.      case 5:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","REVIEWING STATS"); break;
  758.      case 6:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","ACCOUNT EDITING"); break;
  759.      case 7:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","ZOOMING"); break;
  760.      case 8:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","VIEWING DIRS"); break;
  761.      case 9:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","READING BULLS"); break;
  762.     case 10:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","VIEWING FILES"); break;
  763.     case 11:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","ACCOUNT SEQUENCE"); break;
  764.     case 12:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","LOGGING OFF"); break;
  765.     case 13:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","SYSOPING"); break;
  766.     case 14:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","USING SHELL"); break;
  767.     case 15:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","EDITING");break;
  768.     case 16:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","JOINING CONF");break;
  769.     case 17:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","CHATTING");break;
  770.     case 18:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","NODE INACTIVE.");break;
  771.     case 19:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","REQUESTING CHAT");break;
  772.     case 20:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","CONNECTING");break;
  773.     case 21:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","LOGGING ON");break;
  774.     case 22:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","AWAITING CONNECT");break;
  775.     case 23:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","SCANNING MAIL");break;
  776.     case 24:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","SHUTDOWN");break;
  777.     case 25:  sprintf(mes, "%-20.20s | %-25.25s |",Name,Location);sprintf(mes1," %-20.20s |","MULTICHAT");break;
  778.     case 26:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","SUSPENDED");break;
  779.     case 27:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","RESERVED");break;
  780.     case -1:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","UNAVAILABLE");break;
  781.     default:  sprintf(mes, "%-20.20s | %-25.25s |","","");sprintf(mes1," %-20.20s |","");break;
  782.   
  783.   }
  784.   sprintf(mes2,"%d ",i);
  785.   if(status!=27 && status>=0 && status!=24 && status!=18)
  786.   {
  787.     sm(mes2,0); sm(mes,0); sm(mes1,1);
  788.   sm("|---+----------------------+---------------------------+----------------------|",1);
  789.  
  790.   }
  791.   i++;
  792.   }
  793.   sm("`-----------------------------------------------------------------------------'",1);
  794.  
  795.  sm("",1);
  796.  // sm("`--------InfoNode-v2.3a-------------Special Release for-UnLawful Entry--------'",1);
  797.  
  798. }
  799.  
  800. void check_online_status(int rel)
  801. {
  802.    static int opt=0;
  803.    char temp[100];
  804.    switch(opt)
  805.    {
  806.      case 0:
  807.           gu(temp,DT_TIMEUSED);
  808.           Time_Used=atol(temp);
  809.           gu(temp,DT_TIMELIMIT);
  810.           Time_limit=atol(temp);
  811.           opt=1;
  812.           check_online_status(0);
  813.           break;
  814.      case 1:
  815.           Time_system=time(NULL);
  816.           if(Time_holder==0L)
  817.              Time_holder=Time_system;
  818.           Time_Used += Time_system-Time_holder;
  819.           Time_limit -= Time_system-Time_holder;
  820.           Time_holder=Time_system;
  821.           if(Time_limit<=0L)
  822.           {
  823.             timedout=1;
  824.             if(rel)ReleaseSemaphore((struct SignalSemaphore *)Nodes);
  825.             ShutDown();
  826.             end();
  827.           }
  828.           if(Time_limit<300L)
  829.           {
  830.             sm("",1);
  831.             if(Time_limit<60L)
  832.             sprintf(temp,"Warning less than %ld secs remaining",Time_limit+1L);
  833.             else
  834.             sprintf(temp,"Warning less than %ld mins remaining",(Time_limit/60L)+1L);
  835.             sm(temp,1);
  836.           }
  837.           break;
  838.    }
  839. }